package rbac.service;

import java.util.Collection;
import java.util.List;

import rbac.entity.RbacUser;
import rbac.entity.RbacUserGroup;
import rbac.exception.DuplicateUserNameException;
import rbac.exception.EntityDoNotExistException;


/**
 * RBAC service 接口. 负责在 service 层处理<strong>用户</strong>信息.<br>
 * <br>
 * 供访问权限控制接口 <code>AccessControlService</code> 及用户权限管理模块调用.
 * 
 * @see rbac.service.AccessControlService
 * @author Huadi
 * @author Zoufengyang
 */
public interface UserService {

	/**
	 * 通过用户 ID 获取 <code>RbacUser</code>.
	 * 
	 * @param id
	 *            用户 ID.
	 * @return <code>RbacUser</code> 类型的对象. 如果不存在, 返回 <code>null</code>.
	 */
	public RbacUser getUser(Integer id);

	/**
	 * 通过用户名获取 <code>RbacUser</code>.<br>
	 * 用户名称是唯一标识, 可以使用用户名获得唯一对象.
	 * 
	 * @param name
	 *            用户名称.
	 * @return <code>RbacUser</code> 类型的对象. 如果不存在, 返回 <code>null</code>.
	 */
	public RbacUser getUser(String name);

	/**
	 * 通过用户名数组获取 <code>RbacUser</code>.
	 * 
	 * @param userIds
	 *            用户名称集合.
	 * @return
	 */
	public List<RbacUser> getUsers(Collection<Integer> userIds);

	/**
	 * 获取所有 <code>RbacUser</code>.
	 * 
	 * @return 所有系统中存在的用户.
	 */
	public List<RbacUser> getAllUsers();

	/**
	 * 
	 * 持久化一个 <code>RbacUser</code> 实体.
	 * 
	 * @param user
	 *            用户实体.
	 * @throws DuplicateUserNameException
	 *             当系统中已存在同名用户时, 抛出此异常.
	 */
	public void save(RbacUser user) throws DuplicateUserNameException;

	/**
	 * 
	 * 更新一个 <code>RbacUser</code> 实体.
	 * 
	 * @param user
	 *            用户实体.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void update(RbacUser user) throws EntityDoNotExistException;

	/**
	 * 删除一个用户.
	 * 
	 * @param user
	 *            用户实体.
	 */
	public void delete(RbacUser user);

	/**
	 * 删除一个用户.
	 * 
	 * @param user
	 *            用户实体 ID.
	 */
	public void delete(Integer userId);

	/**
	 * 
	 * 将一个用户组的权限赋予一个用户.
	 * 
	 * @param userGroup
	 *            用户组实体.
	 * @param user
	 *            用户实体.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void grantUserGroupToUser(RbacUserGroup userGroup, RbacUser user)
			throws EntityDoNotExistException;

	/**
	 * 将一个用户组的权限赋予一个用户.<br>
	 * 鼓励使用实体进行添加删除操作, <strong>使用此方法会导致数据库 IO 过多</strong>.
	 * 
	 * @param userGroupId
	 *            用户组 ID.
	 * @param userId
	 *            用户 ID.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void grantUserGroupToUser(Integer userGroupId, Integer userId)
			throws EntityDoNotExistException;

	/**
	 * 将一个用户组的权限赋予一个用户.
	 * 
	 * @param userGroupId
	 *            用户 ID.
	 * @param selectedUserIds
	 *            批量添加的用户组 ID.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void grantUserGroupToUser(Integer userId,
			List<Integer> selectedUserGroupIds)
			throws EntityDoNotExistException;

	/**
	 * 将一个用户组的权限赋予一个用户.<br>
	 * 在 RBAC 系统中, 用户名称是唯一的, 所以可以使用用户名得到唯一标识的用户实体.<br>
	 * 
	 * @param userGroupId
	 *            用户组 ID.
	 * @param userName
	 *            用户名称.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void grantUserGroupToUser(Integer userGroupId, String userName)
			throws EntityDoNotExistException;

	/**
	 * 将一个用户组的权限赋予多个用户。<br />
	 * 在 RBAC 系统中，用户名称是唯一的，所以可以使用用户名得到唯一标识的用户实体。<br />
	 * 
	 * @param userGroupId
	 *            用户组 ID
	 * @param userNames
	 *            用户名数组
	 * @throws EntityDoNotExistException
	 *             当传入用户名或用户组 ID 非法时，抛出此异常。
	 */
	public void grantUserGroupToUser(Integer userGroupId,
			Collection<String> userNames) throws EntityDoNotExistException;

	/**
	 * 
	 * 从一个用户收回一个用户组的权限.
	 * 
	 * @param userGroup
	 *            用户组实体.
	 * @param user
	 *            用户实体.
	 * @throws Exception
	 *             当前用户本不在用户组中时, 抛出异常.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void revokeUserGroupFromUser(RbacUserGroup userGroup, RbacUser user)
			throws EntityDoNotExistException;

	/**
	 * 从一个用户收回一个用户组的权限.<br>
	 * 
	 * @param userGroupId
	 *            用户组 ID.
	 * @param userId
	 *            用户 ID.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void revokeUserGroupFromUser(Integer userGroupId, Integer userId)
			throws EntityDoNotExistException;

	/**
	 * 从一个用户收回一个用户组的权限.<br>
	 * 在 RBAC 系统中, 用户名称是唯一的, 所以可以使用用户名得到唯一标识的用户实体.<br>
	 * 
	 * @param userGroupId
	 *            用户组 ID.
	 * @param userName
	 *            用户名称.
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void revokeUserGroupFromUser(Integer userGroupId, String userName)
			throws EntityDoNotExistException;

	/**
	 * 从多个用户处收回一个用户组的权限.<br />
	 * 在 RBAC 系统中, 用户名称是唯一的, 所以可以使用用户名得到唯一标识的用户实体.<br />
	 * 
	 * @param userGroupId
	 *            用户组 ID
	 * @param userNames
	 *            用户名数组
	 * @throws EntityDoNotExistException
	 *             当指定实体不存在时.
	 */
	public void revokeUserGroupFromUser(Integer userGroupId,
			Collection<String> userNames) throws EntityDoNotExistException;

}
